#include "Simon.h"
#include "Global.h"
#include "Directx.h"
#include "Define.h"
#include "Listtexture.h"
#include "whip.h"
Simon::Simon(void){}
Simon::~Simon(void){}
void Simon::Init(int left, int top)
{
	t = 3;
	vx = 0;
	vx_last = 0;
	vy = 0;
	accx = 0.1f;
	accy_increase = 0.25f;
	accy_decrease = 0.05f;
	disx = disy = 0.0f;
	posx = left; 
	posy = top;
	isJump = false;
	isFight = false;
	isMove = true;
	isSit = false;
	onGround = false;
	isUpdate = true;
	isStair = false;
	isGoStair = false;
	animateRate = Listtexture::SIMON_ANIMATERATE;
	lastUpdate = GetTickCount();
	lastAnimate = GetTickCount();
	simon = new Sprite(Listtexture::SIMON, 
		Listtexture::SIMON_WIDTH,Listtexture::SIMON_HEIGHT,Listtexture::SIMON_COUNT,Listtexture::SIMON_SPRITEPERROW);
	width = Listtexture::SIMON_WIDTH;
	height = Listtexture::SIMON_HEIGHT;
	UpdateRect(posx,posy);
}
void Simon::RenderSimon()
{
	Update();
	RECT screen = Global::Screen;
	if(Global::roi->isFight)
	{
		UpdateWhip();
		Global::roi->render();
	}
	simon->Render(backbuffer,rectDraw.left,rectDraw.top,Global::Screen.left,Global::Screen.bottom);
}
void Simon::Update()
{
	if (!Global::roi->isFight)
	{
		isMove = true;

	}
	
		DWORD now = GetTickCount();
		DWORD t = now - lastUpdate;	
		
		if (now - lastUpdate > 1000 / animateRate)
		{
			if (onGround == false && isGoStair == false)
			{
				if (Global::roi->isFight == false)
				{
					if (vx_last > 0.0f)
					{
						simon->Reset(Listtexture::SIMON_SIT_RIGHT);
					}
					else if (vx_last < 0.0f)
					{
						simon->Reset(Listtexture::SIMON_SIT_LEFT);
					}
				}
				vy -= accy_decrease;
				if(onGround == true)
				{
					vy = 0.0f;
					isJump = false;
				}
			}
			if (isJump == true && onGround == true)
			{
					vy = accy_increase;
					onGround = false;
					isJump - false;
			}
			
			else if (isMove)
			{
				
				if(vx < 0.0f) 
					simon->Next(Listtexture::SIMON_MOVE_LEFT_START,Listtexture::SIMON_MOVE_LEFT_END);
				else if(vx > 0.0f) 
					simon->Next(Listtexture::SIMON_MOVE_RIGHT_START,Listtexture::SIMON_MOVE_RIGHT_END);
				else if(vx == 0.0f)
				{
					if(vx_last < 0.0f )
					{
						if (isSit)
						{
							simon->Reset(Listtexture::SIMON_SIT_LEFT);
							
						}
						else simon->Reset(Listtexture::SIMON_MOVE_LEFT_START);
					}
					else if(vx_last > 0.0f)
					{
						if(isSit)
						{
							simon->Reset(Listtexture::SIMON_SIT_RIGHT);

						}
						else simon->Reset(Listtexture::SIMON_MOVE_RIGHT_START);
					}
				}
				
			}
			
			/*else if(isGoStair == false || isStair == false)
			{
				vx = 0;
				vy = 0;
			}*/
			lastUpdate = now;
		}
	disx = vx * t;
	disy = vy * t;
	CollideWithStaticObject();
	
	if (isUpdate == true && Global::roi->isFight == false)
	{
		SimonBox.x += vx * t;
		SimonBox.y += vy * t;
		
		UpdateRect((int)SimonBox.x,(int)SimonBox.y);
	}
	
	
	
}
void Simon::UpdateWhip()
{
	DWORD _now = GetTickCount();
	if (_now - lastAnimate > 1500 / animateRate)
	{
		if(vx_last > 0.0f)
		{

			if (isSit)
			{
				Global::roi->setDirection(1,rectDraw.left, rectDraw.top-16);
				simon->Next(Listtexture::SIMON_SIT_RIGHT_FIGHT_START,Listtexture::SIMON_SIT_RIGHT_FIGHT_END + 1);
				if(simon->_index == Listtexture::SIMON_SIT_RIGHT_FIGHT_END + 1)
				{
					simon->Reset(Listtexture::SIMON_SIT_RIGHT);
				}
			}
			else
			{
				if (isJump)
				{
					Global::roi->setDirection(1,rectDraw.left, rectDraw.top);
				}
				else Global::roi->setDirection(1,rectDraw.left, rectDraw.top);
				simon->Next(Listtexture::SIMON_FIGHT_RIGHT_START,Listtexture::SIMON_FIGHT_RIGHT_END+1);
				if(simon->_index == Listtexture::SIMON_FIGHT_RIGHT_END + 1)
				{
					simon->Reset(Listtexture::SIMON_MOVE_RIGHT_START);
				}
			}
			
		}
		else if (vx_last < 0.0f)
		{
			
			if (isSit)
			{
				Global::roi->setDirection(0,rectDraw.left, rectDraw.top-16);
				simon->Next(Listtexture::SIMON_SIT_LEFT_FIGHT_START,Listtexture::SIMON_SIT_LEFT_FIGHT_END + 1);
				if(simon->_index == Listtexture::SIMON_SIT_LEFT_FIGHT_END + 1)
				{
					simon->Reset(Listtexture::SIMON_SIT_LEFT);
				}
			}
			else
			{
				if (isJump)
				{
					Global::roi->setDirection(0,rectDraw.left, rectDraw.top);
				}
				else Global::roi->setDirection(0,rectDraw.left, rectDraw.top);
				simon->Next(Listtexture::SIMON_FIGHT_LEFT_START,Listtexture::SIMON_FIGHT_LEFT_END+1);
				if(simon->_index == Listtexture::SIMON_FIGHT_LEFT_END + 1 )
				{
					simon->Reset(Listtexture::SIMON_MOVE_LEFT_START);
				}
			}
			

		}
		lastAnimate = _now;
	}
}

void Simon::CollideWithStaticObject()
{
	UpdateSimonBox((float)rectDraw.left, (float)rectDraw.top, (float)width, (float)height,disx, disy);
	list<Static*>::iterator it;
	//trace(L" %f %f %f %f %f %f",SimonBox.x, SimonBox.y,SimonBox.w,SimonBox.h,vx,vy);
	for (it = Global::listStaticObjRender.begin(); it != Global::listStaticObjRender.end(); ++it)
	{
		if ((*it)->isCollide)
		{
			
			Box broadphasebox = Global::collision->GetSweptBroadphaseBox(SimonBox);
			Box staticBox((float)(*it)->rectDraw.left, (float)(*it)->rectDraw.top, (float)(*it)->width, (float)(*it)->height, 0.0f, 0.0f);
			if (Global::collision->AABBCheck(broadphasebox,staticBox))
			{
				float normalx,normaly,collisiontime;
				collisiontime = Global::collision->SweptAABB(SimonBox,staticBox,normalx,normaly);
				//trace(L"%f %f %f", normalx,normaly,collisiontime);

				if (collisiontime >= 0.0f && collisiontime <= 1.0f)
				{
					if ((*it)->type == _BRICK)
					{
						CollideWithBrick(normalx,normaly,collisiontime,(*it));
					}
					else if ((*it)->type == _STAIR_LEFT)
					{
						CollideWithStairLeft(normalx,normaly,collisiontime,(*it));
					}
				}
			}
		}
	}
}
void Simon::CollideWithBrick(float normalx, float normaly, float collisiontime, Static* obj)
{
	if (normaly == 1.0f)
	{
		if (rectDraw.right < obj->rectDraw.left + 1 || rectDraw.left > obj->rectDraw.right + 1)
		{
			isUpdate = true;
			onGround = false;
			return;
		}
		vy = 0;
		onGround = true;
		isJump = false;
		SimonBox.y += disy* collisiontime;
		if (SimonBox.y + SimonBox.h < obj->rectDraw.top)
		{
			SimonBox.y = (float)obj->rectDraw.top + SimonBox.h;
		}
		
		UpdateRect((int)SimonBox.x,(int)SimonBox.y);
		UpdateSimonBox((float)rectDraw.left, (float)rectDraw.top, (float)width, (float)height,disx,0);
		isUpdate = true;
	}

}
void Simon::CollideWithStairLeft(float normalx, float normaly, float collisiontime, Static* obj)
{
	if (isStair == true)
	{
		isStair = false;
	}
	else isStair = true;
	
}
void Simon::ProcessInput()
{
	if(Global::_Directx->IsKeyDown(DIK_LEFT))
	{
		vx = -accx;
		vx_last = vx;
		
	}
	else if(Global::_Directx->IsKeyDown(DIK_RIGHT))
	{
		vx = accx;
		vx_last = vx;
	}
	else if(Global::_Directx->IsKeyDown(DIK_DOWN))
	{
		isSit = true;
	}
	else if(Global::_Directx->IsKeyDown(DIK_UP))
	{
		isGoStair = true;
		if (isGoStair && isStair)
		{
			vx = 0.05f;
			vy = 0.05f;
		}else
		{
			vx =0.0f ;
			vy = 0.0f ;
		}
	}
	else 
	{
		isSit = false;
		vx = 0;	
	}
}
void Simon::OnKeyDown(int keyCode)
{
	switch (keyCode)
	{
	case DIK_NUMPAD1:
		isJump = true;
		break;

	case DIK_NUMPAD2:
		isMove = false;
		Global::roi->isFight = true;
		Global::roi->updateRect(rectDraw.left,rectDraw.top);
		break;
	}
}
void Simon::UpdateSimonBox(float ix, float iy, float iw, float ih, float ivx, float ivy)
{
	SimonBox.x = ix;
	SimonBox.y = iy;
	SimonBox.w = iw;
	SimonBox.h = ih;
	SimonBox.vx = ivx;
	SimonBox.vy = ivy;
}